<style lang="sass" scoped>
.sku_container
  margin-bottom: 30px
  font-size: 12px
  color: #666
  padding: 10px
  border: 1px solid #e5e5e5
  font-size: 12px

.remove
  display: none
  position: absolute
  z-index: 2
  width: 18px
  height: 18px
  font-size: 14px
  line-height: 16px
  color: #fff
  text-align: center
  cursor: pointer
  background: rgba(0,0,0,.3)
  border-radius: 50%

.sku_group
  margin-bottom: 10px
  &:hover
    .spec_title .remove
      display: block

.spec_title
  position: relative
  padding: 7px 10px
  background-color: #f8f8f8
  line-height: 16px
  font-weight: 400

  .label
    display: inline-block
    width: 50px
    margin-right: 5px

  .el-input
    width: 160px

  .remove
    top: 12px
    right: 10px


.group_container
  padding: 10px 10px 0

  .label
    display: inline-block
    width: 50px
    margin-right: 5px

  .el-input
    width: 200px

  .sku_item
    background-color: #f8f8f8
    padding: 10px
    display: inline-block
    margin-right: 10px
    vertical-align: middle
    text-align: center
    position: relative
    border-radius: 2px
    cursor: pointer
    line-height: 1

    &:hover
      .remove
        display: block

    .remove
      top: -8px
      right: -8px

    .text
      display: block
      margin: 0 auto
      overflow: hidden
      text-overflow: ellipsis
      white-space: nowrap
</style>

<template lang="pug">
.container
  //- h3 设置产品规格
  .sku_container
    .sku_group.mb10(v-for="(spec, index) in specification" :key="spec.id")
      .spec_title
        span.label 规格名：
        el-autocomplete(
          class="inline-input"
          placeholder='请输入规格名'
          v-model="spec.value"
          clearable
          :fetch-suggestions="querySearchSkuNames"
          @select="(item) => {onSkuNameSelect(item, spec)}"
          @change.native="(event) => {onSkuNameChange(event, spec)}"
        )
        //- el-input.input(size="small" placeholder='请输入规格名' v-model.trim="spec.value")
        span.remove(@click="delSepc(index)") ×

      .group_container
        span.label 规格值：
        el-popover(
          placement="bottom"
          width="120"
          trigger="click"
          v-for="(option, option_index) in spec.leaf" :key="option_index"
        )
          el-input(size="small" v-model.trim="option.value" style="width: 110px;")
          .sku_item(slot="reference")
            span.remove(@click.stop="delOption(index, option_index)") ×
            .text {{option.value}}

        el-input.input(
          size="small"
          suffix-icon="el-icon-plus"
          v-model="addValues[index]"
          placeholder="多个产品属性以空格隔开"
          @keyup.native.enter='addOption(index)'
          @blur='addOption(index)'
        )
    .spec_title
      el-button(size='small' :disabled='disabled' @click='addSpec') 添加规格项目

  .sku_container(v-show="specification.length > 0")
    SkuTable(:specification.sync="specificationFilter" :productSkus.sync="productSkus" ref="SkuTable")
</template>

<script>
import Vue from 'vue'
import Component from 'vue-class-component'
import SkuTable from './sku-table'
import { createUniqueString, uniqueArr } from '@/utils/util'
import { param2Data } from './sku2param'

@Component({
  props: {
    fetchSkuNames: Function,
    fetchSkuName: Function
  },
  components: {
    SkuTable,
  },
  created() {
    this.getSkuNames()
  }
})
class EditSku extends Vue {
  // 用来存储要添加的规格属性
  addValues = []
  productSkus = []
  specification = []

  get disabled() {
    return (
      this.specification.length > 3 ||
      this.specification.some(item => !item.value)
    )
  }

  get specificationFilter() {
    return this.specification.filter(item => item.value && item.leaf.length)
  }

  // 父组件调用，初始化数据
  _setData(data) {
    if (!data || !data.length) return
    const { productSkus, specification } = param2Data(data)
    this.specification = specification
    this.productSkus = Object.freeze(productSkus)
  }

  // 父组件调用，获取 sku-table 的数据
  _getData() {
    return this.$refs.SkuTable.data
  }

  addSpec() {
    this.specification.push({
      id: createUniqueString() + '_id',
      value: '',
      leaf: [],
    })
  }

  delSepc(index) {
    this.specification.splice(index, 1)
  }

  addOption(index) {
    let str = this.addValues[index] || ''
    str = str.trim()
    if (!str) return
    const oldArr = this.specification[index].leaf
    const arr = str
      .split(/\s+/) // 使用空格分割成数组
      .filter(value => !oldArr.some(option => option.value === value)) // 过滤掉 oldArr 已存在的 value
      .map(value => ({ id: createUniqueString() + '_id', value })) // 把 value 转成对象，id 设置为 null
    this.specification[index].leaf = uniqueArr([...oldArr, ...arr])
    this.$set(this.addValues, index, '')
  }

  delOption(spec_index, option_index) {
    this.specification[spec_index].leaf.splice(option_index, 1)
  }

  // 获取规格名称
  getSkuNames() {
    this.fetchSkuNames((res) => {
      this.skuNames = res
    })
  }

  querySearchSkuNames(queryString, cb) {
    let skuNames = this.skuNames
    let results = queryString ? skuNames.filter(this.createSkuNamesFilter(queryString)) : skuNames
    // 调用 callback 返回建议列表的数据
    cb(results)
  }

  createSkuNamesFilter(queryString) {
    return (k) => {
      return (k.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0)
    }
  }

  onSkuNameChange(event, spec) {
    if (event.target.composing) {
      return;
    }
    let value = event.target.value
    if (!(value.trim())) {
      return false
    }

    if (this.specification.some(option => option.value === value && option !== spec)) {
      event.target.value = ''
      spec.value = ''
      return this.$message({
        type: 'error',
        message: '已经添加了相同的规格名'
      })
    }

    this.fetchSkuName(value, (res) => {
      if (!res) {
        event.target.value = ''
      }
    })
  }

  onSkuNameSelect(item, spec) {
    if (this.specification.some(option => option.value === item.value && option !== spec)) {
      spec.value = ''
      this.$message({
        type: 'error',
        message: '已经添加了相同的规格名'
      })
    }
  }
}

export default EditSku
</script>
